package cn.stylefeng.guns.modular.gridsystem.mqtt;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.stylefeng.guns.modular.gridsystem.netty.entity.RealTime;
import cn.stylefeng.guns.modular.gridsystem.netty.tcp.TcpServerHandler;
import cn.stylefeng.guns.modular.gridsystem.service.BizDeviceService;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayChannelService;
import cn.stylefeng.guns.modular.gridsystem.service.BizGatewayService;
import cn.stylefeng.guns.sys.modular.file.service.SysFileInfoService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.ApplicationContext;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

/**
 * @author ssy
 * @date 2023/3/8 11:35
 */
@Slf4j
public class MyMqttClientCallback implements MqttCallbackExtended {

    private TcpServerHandler tcpServerHandler;

    private BizGatewayService bizGatewayService;
    private BizDeviceService bizDeviceService;
    private BizGatewayChannelService gatewayChannelService;
  // private CollectionDeviceService collectionDeviceService;
    private SysFileInfoService fileInfoService;

    private MyMqttClient client;
    private int connectTimes = 0;

    private RealTime realTime;

    public MyMqttClientCallback(MyMqttClient client) {
        this.client = client;
        ApplicationContext context = SpringUtil.context;  //获取Spring容器
        bizGatewayService = context.getBean(BizGatewayService.class);
        gatewayChannelService = context.getBean(BizGatewayChannelService.class);
        bizDeviceService = context.getBean(BizDeviceService.class);
      //  collectionDeviceService = context.getBean(CollectionDeviceService.class);
        fileInfoService = context.getBean(SysFileInfoService.class);
        realTime = context.getBean(RealTime.class);
        tcpServerHandler = context.getBean(TcpServerHandler.class);
    }

    @Override
    public void connectComplete(boolean b, String s) {
        log.info("————{} 连接成功!————", client.getClientid());
        //连接成功后，自动订阅主题
        client.subscribe();
        connectTimes = 0;
    }

    @Override
    public void connectionLost(Throwable throwable) {
        log.info("————{} 连接丢失!————{}", client.getClientid(), throwable.getCause());
        //可以在此处做重连处理
        if (connectTimes < client.getMaxConnectTimes()) {
            client.refresh();
            connectTimes++;
        } else {
            client.disconnect();
        }
    }

    /**
     * 接收消息
     *
     * @param topic
     * @param mqttMessage
     * @throws Exception
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
        LocalDateTime dateTime = LocalDateTime.now();
        log.info("[MQTT] {} ----成功接收消息！---- 时间： {}", client.getClientid(), dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
        String content = new String(mqttMessage.getPayload());
        log.info("主题 【{}】 接收到消息 : {}", topic, content);
        try {
            JSONObject jsonObject = JSONUtil.parseObj(content);
            String ACTION_POWER = jsonObject.getStr("ACTION_POWER");
            if (ObjectUtil.isNotEmpty(ACTION_POWER)) {
                switch (ACTION_POWER) {
                    case "OFF":
                        tcpServerHandler.setFlag(false);
                        break;
                    case "ON":
                        System.out.println("从采集端拿数据！START");
                        tcpServerHandler.setFlag(true);
                        System.out.println("从采集端拿数据！END");
                    default:
                        break;
                }
            }
        } catch (Exception e) {
            log.info(e.getMessage() + "接收消息异常 {}", Arrays.toString(mqttMessage.getPayload()));
        }

/*

       try {

            JSONObject jsonObject = JSONUtil.parseObj(content);
            String deviceOper = jsonObject.getStr("device_oper");

            if (ObjectUtil.isEmpty(deviceOper)) return;

            List<BizGateway> list = bizGatewayService.list();

            for (BizGateway bizGateway: list){
                String gatewayIp = bizGateway.getGatewayIp();
                String deviceTopic = "deviceControl/" + gatewayIp;
                String similarityTopic = "similarityControl/" + gatewayIp;

                JSONObject object = JSONUtil.parseObj(deviceOper);
                if(topic.equals(deviceTopic)){
                    String gatewayCode = object.getStr("device_id");
                    String param = object.getStr("param");
                    JSONObject paramObject = JSONUtil.parseObj(param);
                    String paths = paramObject.getStr("path");

                    if(ObjectUtil.isNull(paths)){
                        return;
                    }
                    String[] array = paths.split(",");
                    for (String s : array) {
                        boolean endsWith = s.endsWith("/");
                        if (!endsWith) {
                            String channel = s.substring(s.indexOf("-") + 1, s.indexOf("-", s.indexOf("-") + 1));

                            String[] parts = s.split("-");
                            //获取带时间的音频文件名
                            String timeWav = parts[parts.length - 1];

                            final String[] split = timeWav.split("\\.");

                            LambdaQueryWrapper<BizGatewayChannel> queryWrapper = new LambdaQueryWrapper<>();
                            queryWrapper.eq(BizGatewayChannel::getChannel, channel);
                            queryWrapper.eq(BizGatewayChannel::getGatewayId, bizGateway.getId());
                            queryWrapper.last("limit 1");
                            BizGatewayChannel gatewayChannel = gatewayChannelService.getOne(queryWrapper);

                            if (ObjectUtil.isNotNull(gatewayChannel)) {
                                Integer deviceId = gatewayChannel.getDeviceId();

                                final BizDevice bizDevice = bizDeviceService.getById(deviceId);
                                if (ObjectUtil.isNull(bizDevice)) {
                                    throw new ServiceException(MyConst.DEVICE_NOT_EXIST);
                                }

                                String fileName = deviceId + "-" + gatewayCode + "-" + timeWav;
                                final String file = MyFileUtils.downloadFile(s, fileName);

                                MultipartFile multipartFile = new MockMultipartFile(fileName, Files.newInputStream(Paths.get(file)));
                                Long fileId = fileInfoService.uploadFile(multipartFile);

                                log.info("下载文件：{},文件名： {}", s, fileName);

                                if(!FileUtil.exist(file)){
                                    throw new ServiceException(MyConst.FILE_NOT_EXIST);
                                }
                                Librosa.WaveData<byte[]> waveData = Librosa.loadBytes(new File(file));
                                final float sampleRate = waveData.sampleRate;

                                final CollectionDeviceParam deviceParam = new CollectionDeviceParam();
                                deviceParam.setDeviceId(String.valueOf(deviceId));
                                deviceParam.setChannelNo(channel);
                                deviceParam.setVoiceprintName(bizGateway.getGatewayName());
                                deviceParam.setFileName(fileName);
                                deviceParam.setFileId(String.valueOf(fileId));
                                deviceParam.setVoiceprintId(gatewayCode);
                                deviceParam.setDeviceType(bizDevice.getDeviceModel());
                                deviceParam.setFactory(bizDevice.getProductVendor());
                                deviceParam.setPlacementPoint(gatewayChannel.getInstallLocation());
                                deviceParam.setReportStatus("N");
                                if (split.length > 0) {
                                    deviceParam.setGatherTime(DateUtil.formatDateTime(DateUtil.parse(split[0])));
                                }
                                deviceParam.setSamplingRate(String.valueOf(sampleRate));
                                collectionDeviceService.add(deviceParam);
                            }
                        }
                    }

                }else if(topic.equals(similarityTopic)){

                    final String action = object.getStr("action");
                    switch (action){
                        case MessageConst.SIMILARITY_START:
                        case MessageConst.SIMILARITY_STOP:
                        case MessageConst.SIMILARITY_STOP_CONTRAST:
                        case MessageConst.SIMILARITY_START_CONTRAST:
                        case MessageConst.COLLECT_VOICE_MANUAL:
                            break;
                        case MessageConst.SIMILARITY_THRESHOLD:
                            if("sensitive".equals(realTime.getMapCategory())){
                                String param = object.getStr("param");
                                final JSONObject paramObj = JSONUtil.parseObj(param);
                                String score = paramObj.getStr("score");
                                final String[] scores = score.split(",");

                                int channel = Integer.parseInt(realTime.getChannel());
                                String channelScore = scores[channel -1];
                                HashMap<String, Object> hashMap = new HashMap<>();

                                HashMap<String, Object> map = new HashMap<>();
                                map.put("xData",DateUtil.format(new Date(), "HH:mm:ss"));
                                map.put("yData",channelScore);
                                hashMap.put("chartData", map);
                                hashMap.put("soundPressureLevel", String.format("%.1f",realTime.getSoundPressureLevel()));
                                hashMap.put("mapCategory", realTime.getMapCategory());

                                String str = JSONUtil.toJsonStr(hashMap);
                                MyChannelHandlerPool.sendAllMessage(str);
                            }
                            break;
                    }


                }

            }

        } catch (Exception e) {
            log.info(Arrays.toString(mqttMessage.getPayload()));
        }
*/


    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
        log.info("[MQTT]{}  ----成功发送消息！---- 时间： {}", client.getClientid(), LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
    }

}



